﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using AjaxControlToolkit;
using System.Xml.Linq;
using System.Collections;
using System.Collections.Specialized;
using System.Xml.XPath;
using System.Web.Script.Services;
using Microsoft.International.Converters.PinYinConverter;

namespace SharingCenter.Web.Services
{
    using SharingCenter.Web.Classes;
    using System.Web.Security;
    using SharingCenter.Web.Classes.Comments;
    using System.Runtime.Serialization.Json;
    using System.IO;
    using SharingCenter.Web.Classes.Profiles;
    using SharingCenter.Web.Classes.Account;
    /// <summary>
    /// Summary description for ProvinceService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class WebsiteService : System.Web.Services.WebService
    {
        [WebMethod]
        [ScriptMethod]
        public string GetLearningSkillXml()
        {
            string ret = "";
            string xmlPath = Server.MapPath(WebConsts.APPDATA_DIR + "/Skills.xml");
            using (FileStream fs = File.OpenRead(xmlPath))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    ret = sr.ReadToEnd();
                }
            }
         
            return ret;
        }

        [System.Web.Services.WebMethod]
        [System.Web.Script.Services.ScriptMethod]
        public CascadingDropDownNameValue[] GetProvinceDropDownContents(string knownCategoryValues, string category, string contextKey)
        {
            StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
            if (kv.ContainsValue("中国"))
            {

                List<CascadingDropDownNameValue> list = new List<CascadingDropDownNameValue>();
                XDocument doc = XDocument.Load(Server.MapPath("~/App_Data/Provinces.xml"));



                IEnumerable d = doc.Descendants("item");
                bool selected = false;
                foreach (XElement e in d)
                {
                    selected = contextKey == e.Value;
                    list.Add(new CascadingDropDownNameValue(e.Value, e.Value, selected));
                }

                return list.ToArray();
            }
            else
            {
                return null;
            }
        }

        [WebMethod]
        [ScriptMethod]
        public CascadingDropDownNameValue[] GetProvinces(string knownCategoryValues, string category)
        {
            XDocument doc = XDocument.Load(Server.MapPath(WebConsts.APPDATA_DIR + "/china.xml"));
            var q = from t in doc.Root.Elements("province")
                    select t.Attribute("name").Value;
            
            List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
            foreach (string s in q)
            {
                values.Add(new CascadingDropDownNameValue(s, s));
            }

            return values.ToArray();
        }

        [WebMethod]
        [ScriptMethod]
        public CascadingDropDownNameValue[] GetCitiesForProvince(string knownCategoryValues, string category)
        {

            StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

            if (!kv.ContainsKey("Province"))
            {
                return null;
            }

            XDocument doc = XDocument.Load(Server.MapPath(WebConsts.APPDATA_DIR + "/china.xml"));

            var q = from t in doc.Root.Elements("province")
                    where t.Attribute("name").Value == kv["Province"]
                    select t;
            
            List<CascadingDropDownNameValue> list = new List<CascadingDropDownNameValue>();
            foreach (XElement e in q.Descendants("city"))
            {
                list.Add(new CascadingDropDownNameValue(e.Value, e.Value));
            }

            return list.ToArray();
        }

        [System.Web.Services.WebMethod]
        [System.Web.Script.Services.ScriptMethod]
        public CascadingDropDownNameValue[] GetSkillsListContents(string knownCategoryValues, string category)
        {
            StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
            List<CascadingDropDownNameValue> list = new List<CascadingDropDownNameValue>();
            XDocument doc;
            
            if (HttpContext.Current.Cache["SKILLDOC"] == null)
            {
                doc = XDocument.Load(Server.MapPath(string.Format("{0}/Skills.xml", Web.Classes.WebConsts.APPDATA_DIR)));
                HttpContext.Current.Cache["SKILLDOC"] = doc;
            }
            else
            {
                doc = (XDocument)HttpContext.Current.Cache["SKILLDOC"];
            }
            var q = doc.Root.XPathSelectElements("//" + category + "[@Guid='" + kv["undefined"] + "']/Item");
            
            int i = 0;
            bool isDefault = false;

            List<XElement> qList = q.ToList();
            //qList.Add(new XElement("Item", new XAttribute("Name", "其他")));
            
            foreach(XElement el in qList)
            {
                isDefault = i++ == 0;
                list.Add( new CascadingDropDownNameValue(el.Attribute("Name").Value, el.Attribute("Name").Value, isDefault));
            }

            //list.Add(new CascadingDropDownNameValue("其他", "", false));
            
            return list.ToArray();
        }

        [WebMethod]
        [ScriptMethod]
        public List<string> GetPinyin(char hanzi, bool addSound)
        {
            if (ChineseChar.IsValidChar(hanzi))
            {
                ChineseChar ch = new ChineseChar(hanzi);
                List<string> pys = ch.Pinyins.ToList();
                if (!addSound)
                {
                    List<string> r = new List<string>();
                    for (int i = 0; i < pys.Count; i++)
                    {
                        if (pys[i] != null)
                        {
                            string t = pys[i].Substring(0, pys[i].Length - 1);
                            if (!r.Contains(t))
                            {
                                r.Add(t);
                            }
                        }
                    }
                    return r;
                }
                else
                {
                    pys.RemoveAll((d => d == null));
                    return pys;
                }
            }
            return null;
        }

        [WebMethod]
        [ScriptMethod]
        public List<object> GetAbb(string input, char splitter, bool addSound)
        {
            char[] s = { splitter };
            SerializableDictionary<string, List<string>> dic;
            string[] splitted = input.Split(s);
            List<string> val;
            List<object> ret = new List<object>();
            for(int i=0; i<splitted.Length; i++)
            {
                dic = new SerializableDictionary<string, List<string>>(); 
                string str = splitted[i];
                if (str.Length > 1)
                {
                    // non chinese char
                    val = new List<string>();
                    val.Add(str.Substring(0, 1).ToUpper());
                }
                else
                {
                    // chinese char
                    val = GetPinyin(Convert.ToChar(str), addSound);
                }

                dic.Add(str, val);
                ret.Add(dic);
            }
            return ret;
        }

        [WebMethod]
        [ScriptMethod]
        public string[] GetNameByPinyin(string prefixText)
        {
            List<string> ret = new List<string>();
            var q = from t in scDataContext.Instance.Sc_Contacts
                    join p in scDataContext.Instance.Sc_Profiles
                    on t.USerIdB equals p.UserId
                    where p.Pinyin.ToLower().Contains(prefixText.ToLower()) || p.NickName.Contains(prefixText)
                    select new { p.UserId, p.NickName };
            Dictionary<string, string> r = q.ToDictionary(d=>d.UserId.ToString(), d=>d.NickName);
            
            foreach (KeyValuePair<string, string> p in r)
            {
                ret.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(p.Value, p.Key));
            }
            
            return ret.ToArray();
        }

        [WebMethod]
        [ScriptMethod]
        public bool EmailDuplicated(string email)
        {
            return Membership.GetUserNameByEmail(email) != null;
        }

        [WebMethod]
        [ScriptMethod]
        public string GetAvatarPath(string userId, string type)
        {
            //SerializableDictionary<string, string> avatar = new SerializableDictionary<string, string>();
            string ret = string.Empty;

            Guid uid = new Guid(userId);
            Sc_Profile p = ProfileOperations.GetProfile(uid);
            try
            {
                
                
                string path = VirtualPathUtility.ToAbsolute(ProfileOperations.GetAvatarImagePath(uid, Classes.enums.AvatarType.Thumbnail, p));
                //avatar.Add("Normal", path);
                //avatar.Add("Thumb", path);
                //avatar.Add("Tiny", path);
                ret = "[{" + string.Format(@"'Normal':'{0}','Thumb':'{0}','Tiny':'{0}','NickName':'{1}','Online':'{2}'", path, p.NickName, AccountOperations.IsUserOnline(uid)) + "}]";
            }
            catch 
            {
                //avatar.Add("Normal", VirtualPathUtility.ToAbsolute(WebConsts.AVATAR_DEFAULT_IMG_PATH));
                //avatar.Add("Thumb", VirtualPathUtility.ToAbsolute(WebConsts.AVATAR_DEFAULT_IMG_THUMBNAIL_PATH));
                //avatar.Add("Tiny", VirtualPathUtility.ToAbsolute(WebConsts.AVATAR_DEFAULT_IMG_TINY_PATH));

                ret = "[{" + string.Format(" 'Normal':'{0}','Thumb':'{1}','Tiny':'{2}','Online':'false' ", VirtualPathUtility.ToAbsolute(WebConsts.AVATAR_DEFAULT_IMG_PATH),
                VirtualPathUtility.ToAbsolute(WebConsts.AVATAR_DEFAULT_IMG_THUMBNAIL_PATH),
                VirtualPathUtility.ToAbsolute(WebConsts.AVATAR_DEFAULT_IMG_TINY_PATH)
                ) + "}]";
            }
            return ret;
            
        }

        [WebMethod]
        [ScriptMethod]
        public bool AddCommentThread(string appName, string contextName, string contextId, string userId, string content)
        {
            Guid cId, uId;
            try
            {
                cId = new Guid(contextId);
                uId = new Guid(userId);
                CommentOperations.CreateThread(appName, contextName, cId, uId, content);
                return true;
            }
            catch { return false; }
        }

        [WebMethod]
        [ScriptMethod]
        public bool DeleteCommentThread(string threadId)
        {
            Guid tid;
            try
            {
                tid = new Guid(threadId);
            }
            catch { return false; }

            using (scDataContext cxt = new scDataContext())
            {
                try
                {
                    Sc_CommentThread t = cxt.Sc_CommentThreads.Single(d => d.ThreadId == tid);
                    cxt.Sc_CommentThreads.DeleteOnSubmit(t);
                    cxt.SubmitChanges();
                    return true;
                }
                catch { return false; }
            }

        }

        [WebMethod]
        [ScriptMethod]
        public string[] GetEmailList(string prefixText, int count)
        {
            prefixText = prefixText.ToLower().Trim();
            using (scDataContext cxt = new scDataContext())
            {
                var q = from t in cxt.aspnet_Memberships
                        where t.LoweredEmail.StartsWith(prefixText)
                        select t.LoweredEmail;
                return q.ToArray();
            }
        }

        [WebMethod]
        [ScriptMethod]
        public string GetThreadsByContext(string appName, string contextName, string contextId)
        {
            Guid cId;
            try
            {
                cId = new Guid(contextId);
            }
            catch { return null; }

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<List<Sc_Comment>>));
            List<List<Sc_Comment>> ret = new List<List<Sc_Comment>>();
            
            try
            {
                using (scDataContext cxt = new scDataContext())
                {
                    var q = from t in cxt.Sc_CommentThreads
                            where t.ContextName == contextName && t.ContextId == cId && t.AppName == appName
                            orderby t.CreateDate descending
                            select t;
                    
                    foreach (Sc_CommentThread entry in q)
                    {
                        ret.Add(entry.Sc_Comments.ToList());
                    }
                }

                //List<Sc_CommentThread> th = CommentOperations.GetThreads(appName, contextName, cId);
                

                MemoryStream stream1 = new MemoryStream();
                ser.WriteObject(stream1, ret);
                stream1.Position = 0;
                StreamReader sr = new StreamReader(stream1);
                return sr.ReadToEnd();
               
                //return ret;
            }
            catch { return null; }
        }
    }

    
}
